//! 查询方法清单

use super::expr::QueryExprRightValue;
use crate::{
    err::OrmResult,
    model::field::{Field, FieldType},
};
use strum_macros::EnumString;
use time::macros::format_description;

/// Field 查找方法
/// 字段查找是指定 SQL WHERE 子句的方法。它们被指定为 QuerySet 方法 filter()、exclude() 和 get() 的关键字参数。
/// 为方便起见，当没有提供查找类型时（如 get(id=14)），查找类型被假定为 exact。
#[derive(Debug, Default, EnumString)]
pub enum QueryMethod {
    /// 完全匹配。如果提供的比较值是 None，它将被解释为 SQL NULL （详见 isnull）。
    /// 对应方法 : exact
    #[default]
    #[strum(ascii_case_insensitive)]
    Exact,
    /// 不区分大小写的完全匹配。如果提供的比较值是 None，它将被解释为 SQL NULL
    /// 对应方法 : iexact
    #[strum(ascii_case_insensitive)]
    IExact,
    /// 区分大小写的包含测试。
    /// 对应方法 : contains
    #[strum(ascii_case_insensitive)]
    Contains,
    /// 区分大小写的包含测试。
    /// 对应方法 : icontains
    #[strum(ascii_case_insensitive)]
    IContains,
    /// 在一个给定的列表中
    /// 对应方法 : in
    #[strum(ascii_case_insensitive)]
    In,
    /// 大于
    /// 对应方法 : gt
    #[strum(ascii_case_insensitive)]
    Gt,
    /// 大于等于
    /// 对应方法 : gte
    #[strum(ascii_case_insensitive)]
    Gte,
    /// 小于
    /// 对应方法 : lt
    #[strum(ascii_case_insensitive)]
    Lt,
    /// 小于等于
    /// 对应方法 : lte
    #[strum(ascii_case_insensitive)]
    Lte,
    /// 区分大小写的开头为
    /// 对应方法 : startswith
    #[strum(ascii_case_insensitive)]
    Startswith,
    /// 不区分大小写的开头为
    /// 对应方法 : istartswith
    #[strum(ascii_case_insensitive)]
    IStartswith,
    /// 区分大小写的结尾为
    /// 对应方法 : endswith
    #[strum(ascii_case_insensitive)]
    Endswith,
    /// 不区分大小写的结尾为
    /// 对应方法 : iendswith
    #[strum(ascii_case_insensitive)]
    IEndswith,
    /// 范围测试
    /// 对应方法 : range
    #[strum(ascii_case_insensitive)]
    Range,
    /// 对于日期时间字段，将值投射为日期。允许链接其他字段的查找。取一个日期值。
    /// 对应方法 : date，或者两级查询:date__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Date(Box<Self>),
    /// 对于日期和日期时间字段，精确匹配年份。允许链接其他字段的查询。取整数年。
    /// 对应方法 : year，或者两级查询:year__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Year(Box<Self>),
    /// 对于日期和日期时间字段，精确的月份匹配。允许链接其他字段的查询。取整数 1（1 月）到 12（12 月）。
    /// 对应方法 : month，或者两级查询:month__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Month(Box<Self>),
    /// 对于日期和日期时间字段，根据 ISO-8601 ，返回星期号（1-52 或 53），即星期从星期一开始，第一周包含一年的第一个星期四
    /// 对应方法 : week，或者两级查询:week__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Week(Box<Self>),
    /// 对于日期和日期时间字段，“星期几”匹配。允许链接其他字段的查询。从 1（星期日）到 7（星期六）取一个整数值，代表一周的一天。
    /// 对应方法 : week_day，或者两级查询:week_day__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    WeekDay(Box<Self>),
    /// 对于日期和日期时间字段，“一年的四分之一”匹配。允许链接额外的字段查找。取 1 到 4 之间的整数值，代表一年中的季度。
    /// 对应方法 : quarter ，或者两级查询:quarter__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Quarter(Box<Self>),
    /// 对于日期时间字段，将其值强制转换为时间。允许链式附加字段查找。取一个 datetime.time 的值。
    /// 对应方法 : time ，或者两级查询:time__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Time(Box<Self>),
    /// 对于日期时间和时间字段，精确的小时匹配。允许链式查找其他字段。取 0 到 23 之间的整数。
    /// 对应方法 : hour ，或者两级查询:hour__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Hour(Box<Self>),
    /// 对于日期时间和时间字段，精确的分钟匹配。允许链式查找其他字段。取 0 到 59 之间的整数。
    /// 对应方法 : minute ，或者两级查询:minute__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Minute(Box<Self>),
    /// 对于日期时间和时间字段，完全秒配。允许链式查找其他字段。取 0 到 59 之间的整数。
    /// 对应方法 : second ，或者两级查询:second__gt
    ///
    /// 内部方法用于两级查询，默认为：Self::Exact
    #[strum(ascii_case_insensitive)]
    Second(Box<Self>),
    /// 取 True 或 False，分别对应 IS NULL 和 IS NOT NULL 的 SQL 查询。
    #[strum(ascii_case_insensitive)]
    IsNull,
    /// 区分大小写的正则表达式匹配。
    #[strum(ascii_case_insensitive)]
    Regex,
    /// 不区分大小写的正则表达式匹配。
    #[strum(ascii_case_insensitive)]
    IRegex,
}

impl QueryMethod {
    
    /// 生成日期的子项目查询sql
    ///
    /// # 参数说明
    ///
    /// * field 要查询的字段信息
    /// * field_sql 查询字段的sql表示
    /// * value 查询条件
    /// * second_method 二级查询方法
    /// * sql_date_method sql日期方法
    /// * is_time 是否时间相关
    fn to_date_sub_sql(
        field: &Field,
        field_sql: &str,
        value: &QueryExprRightValue,
        second_method: &QueryMethod,
        sql_date_method: &str,
        is_time:bool,
    ) -> OrmResult<String> {
        if !is_time && !matches!(
            field.date_type,
            FieldType::Date | FieldType::DateTime
        ) {
            return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                "{sql_date_method}方法不能用于当前字段,{sql_date_method}方法只能用于日期或日期时间合一字段"
            )))
        }

        if is_time && !matches!(
            field.date_type,
            FieldType::Time | FieldType::DateTime
        ) {
            return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                "{sql_date_method}方法不能用于当前字段,{sql_date_method}方法只能用于时间或日期时间合一字段"
            )))
        }
        // 对应sql日期方法
        let opt = match second_method {
            QueryMethod::Exact => "=",
            QueryMethod::In => "IN",
            QueryMethod::Gt => ">",
            QueryMethod::Gte => ">=",
            QueryMethod::Lt => "<",
            QueryMethod::Lte => "<=",
            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                "{sql_date_method}联动二级方法只能为gt、gte、lt、lte、in,错误的二级查询方法:{second_method:?}"
            )))
        };
        match value {
            QueryExprRightValue::U8(_)
            | QueryExprRightValue::U16(_)
            | QueryExprRightValue::U32(_)
            | QueryExprRightValue::U64(_)
            | QueryExprRightValue::I8(_)
            | QueryExprRightValue::I16(_)
            | QueryExprRightValue::I32(_)
            | QueryExprRightValue::I64(_) => Ok(format!(
                "{sql_date_method}({field_sql}) {opt} {}",
                value.to_sql()
            )),
            QueryExprRightValue::SliceU8(_)
            | QueryExprRightValue::SliceU16(_)
            | QueryExprRightValue::SliceU32(_)
            | QueryExprRightValue::SliceU64(_) => {
                if opt != "IN" {
                    return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                        "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                    )));
                } else {
                    Ok(format!(
                        "{sql_date_method}({field_sql}) {opt} {}",
                        value.to_sql()
                    ))
                }
            }
            _ => {
                return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                    "{sql_date_method}查询值必须为整数:{:#?}",
                    value
                )))
            }
        }
    }
    /// 是否日期相关方法
    pub fn is_date_method(&self) -> bool {
        matches!(
            self,
            QueryMethod::Date(_)
                | QueryMethod::Month(_)
                | QueryMethod::Year(_)
                | QueryMethod::Week(_)
                | QueryMethod::WeekDay(_)
                | QueryMethod::Quarter(_)
                | QueryMethod::Time(_)
                | QueryMethod::Hour(_)
                | QueryMethod::Minute(_)
                | QueryMethod::Second(_)
        )
    }
    /// 是否日期时间的二级子方法相关方法
    pub fn is_date_sub_method(&self) -> bool {
        matches!(
            self,
            QueryMethod::In
                | QueryMethod::Gt
                | QueryMethod::Gte
                | QueryMethod::Lt
                | QueryMethod::Lte
                | QueryMethod::Range
        )
    }
    /// 生成 sql 查询表达式
    ///
    /// @todo 将查询值替换为>，并将值通过QueryParam进行传递，以便防范SQL注入风险 !!!
    /// 
    /// # 参数说明
    /// * field 要查询的字段信息
    /// * field_sql 要查询字段的sql表示
    /// * value 查询条件
    pub fn to_sql(
        &self,
        field: &Field,
        field_sql: &str,
        value: &QueryExprRightValue,
    ) -> OrmResult<String> {
        let sql = match self {
            QueryMethod::Exact => match value {
                QueryExprRightValue::Null => format!("{field_sql} IS {}", value.to_sql()),
                QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                    format!("{field_sql} = '{}'", value.to_sql())
                },
                _ => format!("{field_sql} = {}", value.to_sql()),
            },
            QueryMethod::IExact => {
                if value == &QueryExprRightValue::Null {
                    format!("{field_sql} is {}", value.to_sql())
                } else {
                    format!("{field_sql} ILIKE {}", value.to_sql())
                }
            }
            QueryMethod::Contains => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        let value_sql = value.to_sql();
                        // 去除字符两边的双引号
                        format!("{field_sql} LIKE '%{}%'", value_sql)
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "contains 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::IContains => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        let value_sql = value.to_sql();
                        // 去除字符两边的双引号
                        format!("{field_sql} ILIKE '%{}%'", value_sql)
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "icontains 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::In => format!("{field_sql} IN {}", value.to_sql()),
            QueryMethod::Gt => format!("{field_sql} > {}", value.to_sql()),
            QueryMethod::Gte => format!("{field_sql} >= {}", value.to_sql()),
            QueryMethod::Lt => format!("{field_sql} < {}", value.to_sql()),
            QueryMethod::Lte => format!("{field_sql} <= {}", value.to_sql()),
            QueryMethod::Startswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        let value_sql = value.to_sql();
                        // 去除字符两边的双引号
                        format!("{field_sql} LIKE '{}%'", value_sql)
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "startswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::IStartswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        let value_sql = value.to_sql();
                        // 去除字符两边的双引号
                        format!("{field_sql} ILIKE '{}%'", value_sql)
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "istartswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::Endswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        let value_sql = value.to_sql();
                        // 去除字符两边的双引号
                        format!("{field_sql} LIKE '%{}'", value_sql)
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "endswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::IEndswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        let value_sql = value.to_sql();
                        // 去除字符两边的双引号
                        format!("{field_sql} ILIKE '%{}'", value_sql)
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "iendswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::Range => match value {
                QueryExprRightValue::SliceStr(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN '{}' AND '{}'", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceChar(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN '{}' AND '{}'", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU8(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU16(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU32(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU64(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI8(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI16(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI32(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI64(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceF32(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceF64(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN {} AND {}", value[0], value[1])
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "range 查询值必须为列表，且长度为2 : {:#?}",
                        value
                    )))
                }
            },
            QueryMethod::Date(second_method) => {
                if !matches!(
                    field.date_type,
                    FieldType::Date | FieldType::DateTime
                ) {
                    return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                        "date方法不能用于当前字段,date方法只能用于日期或日期时间合一字段"
                    )))
                }
                // 对应sql日期方法
                let sql_date_method = "date";
                // 支持: date date__gt date__gte date__lt date__lte date__in
                let format = format_description!("[year]-[month]-[day]");
                match value {
                    QueryExprRightValue::SliceStr(date_str_list) => {
                        // 二级联动查询in列表
                        // date__in = ["2023-01-01","2023-03-03"]
                        // 查询值中各个字符串是否均为合法的日期格式,正确格式为: YYYY-DD-MM
                        if date_str_list.iter().find(|date_str| {
                            time::Date::parse(date_str, &format).is_err()
                        }).is_some(){
                            return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}__in查询值非日期字符串列表,列表中字符串应该为YYYY-DD-MM格式:{date_str_list:#?}"
                            )))
                        }
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN {}",value.to_sql()),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::SliceDate(_) => {
                        // 二级联动查询in time:Date列表 
                        // date__in = [date1,date2]                        
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN {}",value.to_sql()),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::Str(value) => {
                        let parse_date = time::Date::parse(value, &format);
                        if parse_date.is_ok(){
                            let opt = match second_method.as_ref() {
                                QueryMethod::Exact => "=",
                                QueryMethod::Gt => ">",
                                QueryMethod::Gte => ">=",
                                QueryMethod::Lt => "<",
                                QueryMethod::Lte => "<=",
                                _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                    "{sql_date_method}查询值为字符串时,联动二级方法只能为gt、gte、lt、lte,错误的二级查询方法:{second_method:?}"
                                )))
                            };
                            format!("{sql_date_method}({field_sql}) {opt} '{value}'")
                        }else{
                            return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                                "{sql_date_method}查询值为字符串时格式必须为:yyyy-mm-dd,错误的日期格式:{:#?}",
                                value
                            )))
                        }
                    },
                    QueryExprRightValue::Date(value) => {
                        let date_sql = value.format(format).expect("转换日期为YYYY-MM-DD格式化日期字符串");
                        format!("{sql_date_method}({field_sql}) = '{date_sql}'")
                    },
                    QueryExprRightValue::DateTime(value) => {
                        let date_sql = value.format(format).expect("转换日期为YYYY-MM-DD格式化日期字符串");
                        format!("{sql_date_method}({field_sql}) = '{date_sql}'")
                    },
                    _ => return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "{sql_date_method}查询值必须为time::Date、time::OffsetDateTime或字符串,为字符串时格式必须为:yyyy-mm-dd,错误的日期格式:{:#?}",
                        value
                    ))),
                }
            }
            QueryMethod::Year(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "year",false)?
            }
            QueryMethod::Month(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "month",false)?
            }
            QueryMethod::Week(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "week",false)?
            }
            QueryMethod::WeekDay(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "weekDay",false)?
            }
            QueryMethod::Quarter(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "quarter",false)?
            }
            QueryMethod::Time(second_method) => {
                if !matches!(
                    field.date_type,
                    FieldType::Time | FieldType::DateTime
                ) {
                    return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                        "time方法不能用于当前字段,time方法只能用于时间或日期时间合一字段"
                    )))
                }
                // 对应sql日期方法
                let sql_date_method = "time";
                // 支持: time time_gt time__gte time__lt time__lte time__in
                let format = format_description!("[hour]:[minute]:[second]");
                match value {
                    QueryExprRightValue::SliceStr(date_str_list) => {
                        // 二级联动查询in列表
                        // time__in = ["10:20:01","13:06:06"]
                        // 查询值中各个字符串是否均为合法的日期格式,正确格式为: HH:MM:SS
                        if date_str_list.iter().find(|date_str| {
                            time::Time::parse(date_str, &format).is_err()
                        }).is_some(){
                            return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}__in查询值非时间字符串列表,列表中字符串应该为HH:MM:SS格式:{date_str_list:#?}"
                            )))
                        }
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN {}",value.to_sql()),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::SliceTime(_) => {
                        // 二级联动查询in time:Time列表 
                        // time__in = [time1,time2]                        
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN {}",value.to_sql()),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::Str(value) => {
                        let parse_date = time::Time::parse(value, &format);
                        if parse_date.is_ok(){
                            let opt = match second_method.as_ref() {
                                QueryMethod::Exact => "=",
                                QueryMethod::Gt => ">",
                                QueryMethod::Gte => ">=",
                                QueryMethod::Lt => "<",
                                QueryMethod::Lte => "<=",
                                _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                    "{sql_date_method}查询值为字符串时,联动二级方法只能为gt、gte、lt、lte,错误的二级查询方法:{second_method:?}"
                                )))
                            };
                            format!("{sql_date_method}({field_sql}) {opt} '{value}'")
                        }else{
                            return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                                "{sql_date_method}查询值为字符串时格式必须为:HH:MM:SS,错误的时间格式:{:#?}",
                                value
                            )))
                        }
                    },
                    QueryExprRightValue::Time(value) => {
                        let date_sql = value.format(format).expect("转换日期为HH:MM:SS格式化时间字符串");
                        format!("{sql_date_method}({field_sql}) = '{date_sql}'")
                    },
                    QueryExprRightValue::DateTime(value) => {
                        let date_sql = value.format(format).expect("转换日期为HH:MM:SS格式化时间字符串");
                        format!("{sql_date_method}({field_sql}) = '{date_sql}'")
                    },
                    _ => return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "{sql_date_method}查询值必须为time::Date、time::OffsetDateTime或字符串,为字符串时格式必须为:HH:MM:SS,错误的时间格式:{:#?}",
                        value
                    ))),
                }
            }
            QueryMethod::Hour(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "hour",true)?
            }
            QueryMethod::Minute(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "minute",true)?
            }
            QueryMethod::Second(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "second",true)?
            }
            QueryMethod::IsNull => match value {
                QueryExprRightValue::Bool(value) => {
                    if *value {
                        format!("{field_sql} IS NULL")
                    } else {
                        format!("{field_sql} IS NOT NULL")
                    }
                }
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "is_null查询值必须为布尔值:{:#?}",
                        value
                    )))
                }
            },
            QueryMethod::Regex => match value {
                QueryExprRightValue::Str(value) => format!("{field_sql} REGEXP BINARY {value}"),
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "regex查询值必须为字符串:{:#?}",
                        value
                    )))
                }
            },
            QueryMethod::IRegex => match value {
                QueryExprRightValue::Str(value) => format!("{field_sql} REGEXP {value}"),
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "iregex查询值必须为字符串:{:#?}",
                        value
                    )))
                }
            },
        };
        Ok(sql)
    }

    /// 生成 sql 查询表达式
    ///
    /// @todo 将查询值替换为>，并将值通过QueryParam进行传递，以便防范SQL注入风险 !!!
    /// 
    /// # 参数说明
    /// * field 要查询的字段信息
    /// * field_sql 要查询字段的sql表示
    /// * value 查询条件
    pub fn to_sql_for_value(
        &self,
        field: &Field,
        field_sql: &str,
        value: &QueryExprRightValue,
    ) -> OrmResult<String> {
        let sql = match self {
            QueryMethod::Exact => match &value {
                QueryExprRightValue::Null => format!("{field_sql} IS {}", value.to_sql()),
                _ => format!("{field_sql} = ?"),
            },
            QueryMethod::IExact => {
                if value == &QueryExprRightValue::Null {
                    format!("{field_sql} is ?")
                } else {
                    format!("{field_sql} ILIKE ?")
                }
            }
            QueryMethod::Contains => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        // 去除字符两边的双引号
                        format!("{field_sql} LIKE ?")
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "contains 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::IContains => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        format!("{field_sql} ILIKE ?")
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "icontains 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::In => format!("{field_sql} IN ?"),
            QueryMethod::Gt => format!("{field_sql} > ?"),
            QueryMethod::Gte => format!("{field_sql} >= ?"),
            QueryMethod::Lt => format!("{field_sql} < ?"),
            QueryMethod::Lte => format!("{field_sql} <= ?"),
            QueryMethod::Startswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        //let value_sql = value.to_sql();
                        // 去除字符两边的双引号
                        format!("{field_sql} LIKE ?")
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "startswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::IStartswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        // 去除字符两边的双引号
                        format!("{field_sql} ILIKE ?")
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "istartswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::Endswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        // 去除字符两边的双引号
                        format!("{field_sql} LIKE %")
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "endswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::IEndswith => {
                // 只能送入字符串或者字符
                match value {
                    QueryExprRightValue::Str(_) | QueryExprRightValue::Char(_) => {
                        // 去除字符两边的双引号
                        format!("{field_sql} ILIKE %")
                    }
                    _ => {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "iendswith 查询值必须为字符串 : {:#?}",
                            value
                        )))
                    }
                }
            }
            QueryMethod::Range => match value {
                QueryExprRightValue::SliceStr(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceChar(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU8(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU16(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU32(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceU64(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI8(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI16(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI32(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceI64(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceF32(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                QueryExprRightValue::SliceF64(value) => {
                    if value.len() == 2 {
                        format!("{field_sql} BETWEEN ? AND ?")
                    } else {
                        return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                            "range 查询值必须长度等于2 : {:#?}",
                            value
                        )));
                    }
                }
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "range 查询值必须为列表，且长度为2 : {:#?}",
                        value
                    )))
                }
            },
            QueryMethod::Date(second_method) => {
                if !matches!(
                    field.date_type,
                    FieldType::Date | FieldType::DateTime
                ) {
                    return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                        "date方法不能用于当前字段,date方法只能用于日期或日期时间合一字段"
                    )))
                }
                // 对应sql日期方法
                let sql_date_method = "date";
                // 支持: date date__gt date__gte date__lt date__lte date__in
                let format = format_description!("[year]-[month]-[day]");
                match value {
                    QueryExprRightValue::SliceStr(date_str_list) => {
                        // 二级联动查询in列表
                        // date__in = ["2023-01-01","2023-03-03"]
                        // 查询值中各个字符串是否均为合法的日期格式,正确格式为: YYYY-DD-MM
                        if date_str_list.iter().find(|date_str| {
                            time::Date::parse(date_str, &format).is_err()
                        }).is_some(){
                            return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}__in查询值非日期字符串列表,列表中字符串应该为YYYY-DD-MM格式:{date_str_list:#?}"
                            )))
                        }
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN ?"),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::SliceDate(_) => {
                        // 二级联动查询in time:Date列表 
                        // date__in = [date1,date2]                        
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN ?"),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::Str(value) => {
                        let parse_date = time::Date::parse(value, &format);
                        if parse_date.is_ok(){
                            let opt = match second_method.as_ref() {
                                QueryMethod::Exact => "=",
                                QueryMethod::Gt => ">",
                                QueryMethod::Gte => ">=",
                                QueryMethod::Lt => "<",
                                QueryMethod::Lte => "<=",
                                _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                    "{sql_date_method}查询值为字符串时,联动二级方法只能为gt、gte、lt、lte,错误的二级查询方法:{second_method:?}"
                                )))
                            };
                            format!("{sql_date_method}({field_sql}) {opt} ?")
                        }else{
                            return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                                "{sql_date_method}查询值为字符串时格式必须为:yyyy-mm-dd,错误的日期格式:{:#?}",
                                value
                            )))
                        }
                    },
                    QueryExprRightValue::Date(_value) => {
                        //let date_sql = value.format(format).expect("转换日期为YYYY-MM-DD格式化日期字符串");
                        format!("{sql_date_method}({field_sql}) = ?")
                    },
                    QueryExprRightValue::DateTime(_value) => {
                        //let date_sql = value.format(format).expect("转换日期为YYYY-MM-DD格式化日期字符串");
                        format!("{sql_date_method}({field_sql}) = ?")
                    },
                    _ => return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "{sql_date_method}查询值必须为time::Date、time::OffsetDateTime或字符串,为字符串时格式必须为:yyyy-mm-dd,错误的日期格式:{:#?}",
                        value
                    ))),
                }
            }
            QueryMethod::Year(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "year",false)?
            }
            QueryMethod::Month(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "month",false)?
            }
            QueryMethod::Week(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "week",false)?
            }
            QueryMethod::WeekDay(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "weekDay",false)?
            }
            QueryMethod::Quarter(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "quarter",false)?
            }
            QueryMethod::Time(second_method) => {
                if !matches!(
                    field.date_type,
                    FieldType::Time | FieldType::DateTime
                ) {
                    return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                        "time方法不能用于当前字段,time方法只能用于时间或日期时间合一字段"
                    )))
                }
                // 对应sql日期方法
                let sql_date_method = "time";
                // 支持: time time_gt time__gte time__lt time__lte time__in
                let format = format_description!("[hour]:[minute]:[second]");
                match value {
                    QueryExprRightValue::SliceStr(date_str_list) => {
                        // 二级联动查询in列表
                        // time__in = ["10:20:01","13:06:06"]
                        // 查询值中各个字符串是否均为合法的日期格式,正确格式为: HH:MM:SS
                        if date_str_list.iter().find(|date_str| {
                            time::Time::parse(date_str, &format).is_err()
                        }).is_some(){
                            return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}__in查询值非时间字符串列表,列表中字符串应该为HH:MM:SS格式:{date_str_list:#?}"
                            )))
                        }
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN ?"),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::SliceTime(_) => {
                        // 二级联动查询in time:Time列表 
                        // time__in = [time1,time2]                        
                        match second_method.as_ref() {
                            QueryMethod::In => format!("{sql_date_method}({field_sql}) IN ?"),
                            _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                "{sql_date_method}查询值为列表时,联动二级方法只能为in,错误的二级查询方法:{second_method:?}"
                            )))
                        }
                    },
                    QueryExprRightValue::Str(value) => {
                        let parse_date = time::Time::parse(value, &format);
                        if parse_date.is_ok(){
                            let opt = match second_method.as_ref() {
                                QueryMethod::Exact => "=",
                                QueryMethod::Gt => ">",
                                QueryMethod::Gte => ">=",
                                QueryMethod::Lt => "<",
                                QueryMethod::Lte => "<=",
                                _ => return Err(crate::err::OrmError::IncorrectQueryMethod(format!(
                                    "{sql_date_method}查询值为字符串时,联动二级方法只能为gt、gte、lt、lte,错误的二级查询方法:{second_method:?}"
                                )))
                            };
                            format!("{sql_date_method}({field_sql}) {opt} ?")
                        }else{
                            return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                                "{sql_date_method}查询值为字符串时格式必须为:HH:MM:SS,错误的时间格式:{:#?}",
                                value
                            )))
                        }
                    },
                    QueryExprRightValue::Time(_value) => {
                        //let date_sql = value.format(format).expect("转换日期为HH:MM:SS格式化时间字符串");
                        format!("{sql_date_method}({field_sql}) = ?")
                    },
                    QueryExprRightValue::DateTime(_value) => {
                        //let date_sql = value.format(format).expect("转换日期为HH:MM:SS格式化时间字符串");
                        format!("{sql_date_method}({field_sql}) = ?")
                    },
                    _ => return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "{sql_date_method}查询值必须为time::Date、time::OffsetDateTime或字符串,为字符串时格式必须为:HH:MM:SS,错误的时间格式:{:#?}",
                        value
                    ))),
                }
            }
            QueryMethod::Hour(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "hour",true)?
            }
            QueryMethod::Minute(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "minute",true)?
            }
            QueryMethod::Second(second_method) => {
                Self::to_date_sub_sql(field,field_sql, value, &second_method, "second",true)?
            }
            QueryMethod::IsNull => match value {
                QueryExprRightValue::Bool(value) => {
                    if *value {
                        format!("{field_sql} IS NULL")
                    } else {
                        format!("{field_sql} IS NOT NULL")
                    }
                }
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "is_null查询值必须为布尔值:{:#?}",
                        value
                    )))
                }
            },
            QueryMethod::Regex => match value {
                QueryExprRightValue::Str(_value) => format!("{field_sql} REGEXP BINARY ?"),
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "regex查询值必须为字符串:{:#?}",
                        value
                    )))
                }
            },
            QueryMethod::IRegex => match value {
                QueryExprRightValue::Str(_value) => format!("{field_sql} REGEXP ?"),
                _ => {
                    return Err(crate::err::OrmError::IncorrectQueryValue(format!(
                        "iregex查询值必须为字符串:{:#?}",
                        value
                    )))
                }
            },
        };
        Ok(sql)
    }
}
